/**
 * 客户端工厂
 * 使用工厂模式创建不同类型的客户端
 */

/**
 * 客户端类型枚举
 */
const ClientTypes = {
  STREAMING: 'streaming',
  HTTP: 'http',
  WEBSOCKET: 'websocket'
}

/**
 * 客户端工厂类
 */
class ClientFactory {
  /**
   * 创建客户端实例
   * @param {string} type 客户端类型
   * @param {string} url 连接URL
   * @param {Object} options 配置选项
   * @returns {Object} 客户端实例
   */
  static createClient(type, url, options = {}) {
    switch (type) {
      case ClientTypes.STREAMING:
        return this.createStreamingClient(url, options)
      
      case ClientTypes.HTTP:
        // 对于HTTP客户端，我们返回一个简单的对象
        return {
          type: ClientTypes.HTTP,
          url,
          options,
          request: this.createHttpRequest.bind(this, url, options)
        }
      
      case ClientTypes.WEBSOCKET:
        // WebSocket客户端实现
        return this.createWebSocketClient(url, options)
      
      default:
        throw new Error(`不支持的客户端类型: ${type}`)
    }
  }
  
  /**
   * 创建流式客户端
   * @param {string} url 请求URL
   * @param {Object} options 配置选项
   * @returns {Object} 流式客户端实例
   */
  static createStreamingClient(url, options) {
    let requestTask = null;
    const listeners = {};

    const _dispatchEvent = (event, data) => {
        if (listeners[event]) {
            listeners[event].forEach(callback => callback(data));
        }
    };

    return {
        type: ClientTypes.STREAMING,
        url,
        options,

        addEventListener(event, callback) {
            if (!listeners[event]) {
                listeners[event] = [];
            }
            listeners[event].push(callback);
        },

        connect() {
            if (requestTask) return;

            requestTask = uni.request({
                url: url,
                method: options.method || 'POST',
                header: options.headers,
                data: options.body,
                enableChunked: true,
                success: (res) => {
                    _dispatchEvent('close');
                },
                fail: (error) => {
                    _dispatchEvent('error', error);
                }
            });

            let buffer = '';
            requestTask.onChunkReceived((res) => {
                buffer += new TextDecoder('utf-8').decode(new Uint8Array(res.chunk));
                const parts = buffer.split('\n\n');
                buffer = parts.pop() || '';
                parts.forEach(p => {
                    if (p.startsWith('data:')) {
                        const text = p.slice(5).trim();
                        if (text !== '[END]') {
                            _dispatchEvent('message', { data: text });
                        }
                    }
                });
            });
            
            _dispatchEvent('open');
        },

        close() {
            if (requestTask) {
                requestTask.abort();
                requestTask = null;
            }
        }
    };
  }

  /**
   * 创建HTTP请求函数
   * @param {string} url 请求URL
   * @param {Object} options 配置选项
   * @returns {Function} 请求函数
   */
  static createHttpRequest(url, options) {
    return (data) => {
      return new Promise((resolve, reject) => {
        uni.request({
          url,
          method: options.method || 'GET',
          data: data || options.data,
          header: options.headers || {},
          success: (res) => {
            if (res.statusCode === 200) {
              resolve(res.data)
            } else {
              reject(new Error(`HTTP ${res.statusCode}: ${res.errMsg}`))
            }
          },
          fail: (err) => {
            reject(err)
          }
        })
      })
    }
  }
  
  /**
   * 创建WebSocket客户端
   * @param {string} url WebSocket URL
   * @param {Object} options 配置选项
   * @returns {Object} WebSocket客户端
   */
  static createWebSocketClient(url, options) {
    let socketTask = null
    
    return {
      type: ClientTypes.WEBSOCKET,
      url,
      options,
      
      /**
       * 连接到WebSocket服务器
       */
      connect() {
        return new Promise((resolve, reject) => {
          try {
            socketTask = uni.connectSocket({
              url,
              ...options,
              success: () => {
                resolve()
              },
              fail: (err) => {
                reject(err)
              }
            })
          } catch (error) {
            reject(error)
          }
        })
      },
      
      /**
       * 发送消息
       * @param {any} data 消息数据
       */
      send(data) {
        if (!socketTask) {
          throw new Error('WebSocket未连接')
        }
        
        return new Promise((resolve, reject) => {
          socketTask.send({
            data: typeof data === 'string' ? data : JSON.stringify(data),
            success: () => {
              resolve()
            },
            fail: (err) => {
              reject(err)
            }
          })
        })
      },
      
      /**
       * 关闭连接
       */
      close() {
        if (socketTask) {
          socketTask.close()
          socketTask = null
        }
      },
      
      /**
       * 监听消息
       * @param {Function} callback 回调函数
       */
      onMessage(callback) {
        if (!socketTask) {
          throw new Error('WebSocket未连接')
        }
        
        socketTask.onMessage((res) => {
          callback(res.data)
        })
      },
      
      /**
       * 监听连接打开
       * @param {Function} callback 回调函数
       */
      onOpen(callback) {
        if (!socketTask) {
          throw new Error('WebSocket未连接')
        }
        
        socketTask.onOpen(() => {
          callback()
        })
      },
      
      /**
       * 监听连接关闭
       * @param {Function} callback 回调函数
       */
      onClose(callback) {
        if (!socketTask) {
          throw new Error('WebSocket未连接')
        }
        
        socketTask.onClose(() => {
          callback()
        })
      },
      
      /**
       * 监听错误
       * @param {Function} callback 回调函数
       */
      onError(callback) {
        if (!socketTask) {
          throw new Error('WebSocket未连接')
        }
        
        socketTask.onError((err) => {
          callback(err)
        })
      }
    }
  }
}

// 导出工厂和类型枚举
export { ClientFactory, ClientTypes }
export default ClientFactory
